package org.budo.support.application.registry;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.budo.support.lang.util.ListUtil;
import org.budo.support.lang.util.ProcessUtil;
import org.budo.support.lang.util.ReflectUtil;
import org.budo.support.spring.util.SpringUtil;
import org.budo.time.Time;
import org.budo.time.TimePoint;
import org.springframework.context.ApplicationContext;

/**
 * @author lmw
 */
public class BudoApplicationUtil {
    public static String getApplicationName() {
        String targetType = "org.budo.graph.service.util.BudoGraphApplicationUtil";
        String methodName = "getApplicationName";
        return (String) ReflectUtil.invokeMethod_3(targetType, methodName, null, null, null);
    }

    public static String upstream(ApplicationContext applicationContext, Boolean verbose) {
        BudoApplicationRegistry applicationRegistry = SpringUtil.getBean(applicationContext, BudoApplicationRegistry.class);
        if (null == applicationRegistry) {
            return "no applicationRegistry";
        }

        List<BudoApplication> applications = applicationRegistry.lookup(BudoApplicationRegistry.APPLICATION_NAME_ANY);
        Map<String, List<BudoApplication>> applicationGroupMap = ListUtil.groupByField(applications, BudoApplication::getName);

        String responseBody = "";
        responseBody += upstreamHead(verbose);
        responseBody += upstreamMain(applicationGroupMap, verbose);

        return responseBody;
    }

    private static String upstreamHead(Boolean verbose) {
        String upstreamHead = "";
        upstreamHead += "#\n";
        upstreamHead += "# budo upstream\n";

        if (null != verbose && verbose) { // 显示指定为 非简洁
            upstreamHead += "# now = " + Time.now().toString("yyyyMMdd.HHmmss.SSS") + "\n";
            upstreamHead += "# processId = " + ProcessUtil.getCurrentProcessId() + "\n";
            upstreamHead += "# processName = " + ProcessUtil.getCurrentProcessName() + "\n";
        }

        upstreamHead += "#\n\n";
        return upstreamHead;
    }

    public static String upstreamMain(Map<String, List<BudoApplication>> applicationGroupMap, Boolean verbose) {
        String upstreamMain = "";

        for (Entry<String, List<BudoApplication>> entry : applicationGroupMap.entrySet()) {
            String key = entry.getKey();
            List<BudoApplication> apps = entry.getValue();

            // 排序 启动时间后的优先
            apps.sort((a, b) -> b.getStartAt().compareTo(a.getStartAt())); // b compareTo a // 大的优先 先启动的优先

            upstreamMain += "upstream " + key + " { \n";
            upstreamMain += "    zone " + key + " 1m;\n\n";
            upstreamMain += "    ip_hash;\n\n";

            for (BudoApplication app : apps) {
                String name = app.getName();
                TimePoint _startAt = Time.when(app.getStartAt());
                String startAt = _startAt.toString("MMdd.HHmm");
                String uptime = _startAt.betweenNow().toString();
                String createdAt = Time.when(app.getCreateAt()).toString("HH:mm");

                if (null != verbose && verbose) { // 显示指定为 非简洁
                    upstreamMain += "    server " + app.getIp() + ":" + app.getPort() + "; #" + name + ", start " + startAt + ", up " + uptime + ", create " + createdAt + "\n";
                } else {
                    upstreamMain += "    server " + app.getIp() + ":" + app.getPort() + "; #" + name + ", start " + startAt + "\n";
                }
            }

            upstreamMain += "} \n\n";
        }
        return upstreamMain;
    }
}